package com.ywy.bootadmin.task;

import com.ywy.bootadmin.model.sys.Task;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 定时任务管理
 *
 * @author ywy
 * @date 2021/11/3 17:34
 */
@Component
public class QuartzManager {
    @Autowired
    private Scheduler scheduler;

    /**
     * 添加任务
     *
     * @param task
     */
    public void addJob(Task task) throws SchedulerException {
        Class<? extends Job> taskClass = null;
        try {
            taskClass = (Class<? extends Job>) (Class.forName(task.getBeanClass()).newInstance().getClass());
        } catch (Exception e) {
            e.printStackTrace();
            throw new SchedulerException(e);
        }
        // 构建job信息，指明任务执行类，任务名，任务组，任务名称和组构成任务key
        JobDetail jobDetail = JobBuilder.newJob(taskClass).withIdentity(task.getJobName(), task.getJobGroup()).build();
        // 构建trigger，定义调度触发规则
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(task.getJobName(), task.getJobGroup()) // 触发器名，触发器组
                .startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND))
                .withSchedule(CronScheduleBuilder.cronSchedule(task.getCronExpression())) // 触发器时间
                .startNow().build();
        // 把作业和触发器注册到任务调度中
        scheduler.scheduleJob(jobDetail, trigger);
        // 启动调度器
        if (!scheduler.isShutdown()) {
            scheduler.start();
        }
    }

    /**
     * 获取所有任务
     * @return
     * @throws SchedulerException
     */
    public List<Task> getAllJob() throws SchedulerException {
        GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
        Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
        List<Task> jobList = new ArrayList<Task>();
        for (JobKey jobKey : jobKeys) {
            List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
            for (Trigger trigger : triggers) {
                Task task = new Task();
                task.setJobName(jobKey.getName());
                task.setJobGroup(jobKey.getGroup());
                task.setDescription("触发器:" + trigger.getKey());
                Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                task.setJobStatus(triggerState.ordinal());
                if (trigger instanceof CronTrigger) {
                    CronTrigger cronTrigger = (CronTrigger) trigger;
                    String cronExpression = cronTrigger.getCronExpression();
                    task.setCronExpression(cronExpression);
                }
                jobList.add(task);
            }
        }
        return jobList;
    }

    /**
     * 获取所有正在运行的任务
     * @return
     * @throws SchedulerException
     */
    public List<Task> getRunningJob() throws SchedulerException {
        List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
        List<Task> jobList = new ArrayList<Task>(executingJobs.size());
        for (JobExecutionContext executingJob : executingJobs) {
            Task task = new Task();
            JobDetail jobDetail = executingJob.getJobDetail();
            JobKey jobKey = jobDetail.getKey();
            Trigger trigger = executingJob.getTrigger();
            task.setJobName(jobKey.getName());
            task.setJobGroup(jobKey.getGroup());
            task.setDescription("触发器:" + trigger.getKey());
            Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
            task.setJobStatus(triggerState.ordinal());
            if (trigger instanceof CronTrigger) {
                CronTrigger cronTrigger = (CronTrigger) trigger;
                String cronExpression = cronTrigger.getCronExpression();
                task.setCronExpression(cronExpression);
            }
            jobList.add(task);
        }
        return jobList;
    }

    /**
     * 暂停任务
     * @param task
     * @throws SchedulerException
     */
    public void pauseJob(Task task) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());
        scheduler.pauseJob(jobKey);
    }

    /**
     * 恢复任务
     * @param task
     * @throws SchedulerException
     */
    public void resumeJob(Task task) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());
        scheduler.resumeJob(jobKey);
    }

    /**
     * 删除任务
     * @param task
     * @throws SchedulerException
     */
    public void deleteJob(Task task) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());
        scheduler.deleteJob(jobKey);
    }

    /**
     * 立即触发
     * @param task
     * @throws SchedulerException
     */
    public void runJobNow(Task task) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());
        scheduler.triggerJob(jobKey);
    }

    /**
     * 更新job表达式
     * @param task
     * @throws SchedulerException
     */
    public void updateJobCron(Task task) throws SchedulerException {
        TriggerKey triggerKey = TriggerKey.triggerKey(task.getJobName(), task.getJobGroup());
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        // 表达式调度构建器
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.getCronExpression());
        // 按新的cron表达式重新构建trigger
        trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
        // 重新设置job执行
        scheduler.rescheduleJob(triggerKey, trigger);
    }
}
